package com.ruoyi.accountant.service.impl;

import com.ruoyi.web.core.config.AppConf;
import com.ruoyi.accountant.domain.Balance;
import com.ruoyi.accountant.domain.Inaccount;
import com.ruoyi.accountant.domain.TransactionDetail;
import com.ruoyi.accountant.mapper.BalanceMapper;
import com.ruoyi.accountant.mapper.InaccountMapper;
import com.ruoyi.accountant.mapper.TransactionDetailMapper;
import com.ruoyi.accountant.service.InaccountService;
import com.ruoyi.web.web.form.UnfinishedForm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.List;

@Transactional
@Service
public class InaccountServiceImpl implements InaccountService {

    @Autowired
    private InaccountMapper inaccountMapper;

    @Autowired
    private BalanceMapper balanceMapper;

    @Autowired
    private TransactionDetailMapper transactionDetailMapper;

    @Override
    public void save(Inaccount inaccount) {
        inaccountMapper.insert(inaccount);
    }

    @Override
    public List<Inaccount> findUnfinishedByForm(UnfinishedForm form) {
        Specification<Inaccount> specification = new Specification<Inaccount>() {
            @Override
            public Predicate toPredicate(Root<Inaccount> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate and = criteriaBuilder.and(criteriaBuilder.equal(root.get("finished"), AppConf.OFF)); // 未完成的

                if(form.getTransactionType() != null && !"不限".equals(form.getTransactionType())) {
                    and = criteriaBuilder.and(and, criteriaBuilder.equal(root.get("dtype"), form.getTransactionType()));
                }

                if(form.getOfReason() != null && (-1 != form.getOfReason())) {
                    and = criteriaBuilder.and(and, criteriaBuilder.equal(root.get("ofReason"), form.getOfReason()));
                }

                if(!StringUtils.isEmpty(form.getOther())) {
                    Predicate object = criteriaBuilder.like(root.get("object"), "%"+form.getOther()+"%");
                    Predicate tag = criteriaBuilder.like(root.get("tag"), "%"+form.getOther()+"%");
                    Predicate invoice = criteriaBuilder.like(root.get("invoice"), "%"+form.getOther()+"%");
                    Predicate comment = criteriaBuilder.like(root.get("comment"), "%"+form.getOther()+"%");

                    and = criteriaBuilder.and(and, criteriaBuilder.or(object, tag, invoice, comment));
                }

                return criteriaQuery.where(and).getRestriction();
            }
        };

        return inaccountMapper.selectByExample(null);
    }

    @Override
    public void deleteById(Long iid) {
        inaccountMapper.deleteByPrimaryKey(iid);
    }

    @Override
    public void finish(Long iid) {
        Inaccount inaccount = inaccountMapper.selectByPrimaryKey(iid);

        //转入
        Balance inbalance = balanceMapper.findAllByOfAccountAndOfCurrency(inaccount.getInaccount(), inaccount.getInaccountCurrency());
        if(inbalance == null) { // 如果目标账户没有此币种类型的余额
            inbalance = new Balance();
            inbalance.setOfCurrency(inaccount.getInaccountCurrency());
            inbalance.setOfAccount(inaccount.getInaccount());
            inbalance.setCreatetime(new Timestamp(System.currentTimeMillis()));
            inbalance.setBalance(new BigDecimal(0));
        }

        // 加入(转入 - 手续费)
        inbalance.add(inaccount.getInaccountMoney().subtract(new BigDecimal(inaccount.getInaccountServiceCharge())));

        balanceMapper.insert(inbalance);

        // 将交易记录标记完成
        TransactionDetail detail = transactionDetailMapper.selectByPrimaryKey(inaccount.getTid());
        detail.setFinished(AppConf.ON);
        transactionDetailMapper.updateByPrimaryKeySelective(detail);

        inaccount.setFinished(AppConf.ON);
        inaccountMapper.insert(inaccount);
    }

    @Override
    public int doInaccount() {
        // 查询endtime到期，并且是收入的交易
        List<Inaccount> inaccountList = inaccountMapper.findTransferEnd();
        // 执行转移到账
        for (Inaccount inaccount : inaccountList) {
            BigDecimal outaccountMoney = inaccount.getOutaccountMoney();
            // 查询账户余额
            Balance b = balanceMapper.findAllByOfAccountAndOfCurrency(inaccount.getInaccount(), inaccount.getInaccountCurrency());
            if(b == null) { // 余额不存在
                b = new Balance();

                b.setOfCurrency(inaccount.getInaccountCurrency());
                b.setOfAccount(inaccount.getInaccount());
                b.setCreatetime(new Timestamp(System.currentTimeMillis()));
                b.setBalance(outaccountMoney);
            } else {
                b.add(outaccountMoney);
            }
            balanceMapper.insert(b);

            // 删除
            inaccountMapper.deleteByPrimaryKey(inaccount.getIid());
        }

        return inaccountList.size();
    }

    @Override
    public Inaccount findById(Long iid) {
        return inaccountMapper.selectByPrimaryKey(iid);
    }
}
